/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.academik.controller;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.model.SelectItem;
import org.academik.model.Catalogoservicios;
import org.academik.model.Detallerecibo;
import org.academik.model.DetallereciboId;
import org.academik.model.Recibo;
import org.academik.model.Serie;
import org.academik.util.FacesUtil;
import org.academik.util.HibernateUtil;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author Javier
 */
@ManagedBean(name = "recibosBean")
@ViewScoped
public class RecibosBean extends AbstractViewScopedBean implements Serializable {

    /** Declaracion de Variables*/
    private Recibo recibo;
    private Detallerecibo detalleRecibo;
    private ArrayList listaRecibos;
    private Long selectedConcepto;
    private String detalleConcepto;
    private ArrayList<Object[]> arregloDetalles;
    private double totalPagar;
    private Object[] selectedPago;
    private Long selectedSerie;
    private Object[] selectedRecibo;
    private boolean boEditar;

    /** Creates a new instance of RecibosBean */
    public RecibosBean() {
        this.nuevo();
    }

    @Override
    public void crear() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
            tx = (Transaction) session.beginTransaction();
            Serie tempSerie = (Serie) session.load(Serie.class, this.selectedSerie);
            tempSerie.setNuUltimoValor(this.recibo.getNuNumRecibo());
            session.saveOrUpdate(tempSerie); //Actualiza ultimo valor de la serie
            
            this.recibo.setBoPendientePago(false);
            if (this.recibo.getNuCantidadDeuda() > 0) {
                this.recibo.setBoPendientePago(true);
            }

            this.recibo.setSerie(tempSerie);
            this.recibo.setNuTotal(this.totalPagar);
            session.saveOrUpdate(this.recibo); //Actualizar o guardar el recibo

            if (this.boEditar == true) { //Si es modificacion elimine datos viejos del detellarecibo
                String sql = "DELETE FROM detallerecibo "
                        + "WHERE recibo_idRecibo = :id";
                Query query = session.createSQLQuery(sql);
                query.setParameter("id", this.recibo.getIdRecibo());
                query.executeUpdate();
                this.boEditar = false;
            }

            Iterator iter = this.arregloDetalles.iterator();
            while (iter.hasNext()) {
                Object[] obj = (Object[]) iter.next();
                Detallerecibo tempDetalle = (Detallerecibo) obj[1];
                Long idServicio = (Long) obj[2];

                DetallereciboId tempIdDetalle = new DetallereciboId();
                tempIdDetalle.setReciboIdRecibo(this.recibo.getIdRecibo());
                tempIdDetalle.setCatalogoServiciosIdCatalogoServicios(idServicio);

                tempDetalle.setRecibo(this.recibo);
                tempDetalle.setId(tempIdDetalle);
                session.saveOrUpdate(tempDetalle); //Almacena el detalle                
            }
            session.flush();
            session.clear();
            tx.commit();
            this.nuevo();
            FacesContext.getCurrentInstance().addMessage(null,
                    new FacesMessage(FacesMessage.SEVERITY_INFO, "Información:", "El recibo se creo satisfactoriamente"));
        } catch (HibernateException e) {
            tx.rollback();
            FacesUtil.hibernateException(e);
        } finally {
            session.close();
        }
    }

    @Override
    public void eliminar() {
        /* Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        try {
        tx = (Transaction) session.beginTransaction();
        Detallerecibo dr = (Detallerecibo) session.load(Detallerecibo.class, this.selectedRecibo[1].toString());
        session.delete(dr); //Elimina los detalles del recibo por la fk
        
        //Falta colocar DetallereciboId
        
        Recibo r = (Recibo) session.load(Recibo.class, this.selectedRecibo[1].toString());
        session.delete(r); //Elimina el recibo
        tx.commit();
        this.nuevo();
        FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Información:", "Registro eliminado satisfactoriamente"));
        } catch (HibernateException e) {
        tx.rollback();
        FacesUtil.hibernateException(e);
        } finally {
        session.close();
        }*/
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void cargarOpciones() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void cargarOpciones(int id) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void buscar() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void modificar() {
        this.totalPagar = 0;
        this.arregloDetalles = new ArrayList<Object[]>();

        Session session = HibernateUtil.getSessionFactory().openSession();
        this.recibo = (Recibo) session.load(Recibo.class, Long.parseLong(this.selectedRecibo[0].toString()));

        
        String sql = "SELECT dr FROM Detallerecibo dr "
                + "WHERE dr.recibo = :parametro";
        Query query = session.createQuery(sql);
        query.setParameter("parametro", this.recibo);

        Iterator iter = query.list().iterator();
        while (iter.hasNext()) {
            Detallerecibo tempDetalle = (Detallerecibo) iter.next();

            Object[] obj = new Object[3];
            obj[0] = tempDetalle.getCatalogoservicios().getVcConceptoServicio();
            obj[1] = tempDetalle;
            obj[2] = tempDetalle.getCatalogoservicios().getIdCatalogoServicios();

            this.totalPagar += tempDetalle.getNuPrecio() * tempDetalle.getNuCantidad();
            this.arregloDetalles.add(obj);
        }
        session.close();
        this.boEditar = true;
    }

    @Override
    public void cargarResgistros() {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    @Override
    public void nuevo() {
        this.recibo = new Recibo();
        this.detalleRecibo = new Detallerecibo();
        this.listaRecibos = new ArrayList();
        this.selectedConcepto = null;
        this.detalleConcepto = null;
        this.arregloDetalles = new ArrayList<Object[]>();
        this.totalPagar = 0;
        this.selectedPago = new Object[2];
        this.selectedSerie = null;
        this.selectedRecibo = null;
        this.boEditar = false;

        this.populateRecibos();
    }

    /** Muestra los datos de la BD en la tabla*/
    public void populateRecibos() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        String sql = "SELECT r.*, (SELECT SUM(dr.`nuCantidad`*dr.`nuPrecio`)), dr.* "
                + "FROM recibo r "
                + "JOIN detalleRecibo dr "
                + "ON r.`idRecibo`=dr.`recibo_idRecibo` "
                + "GROUP BY dr.`recibo_idRecibo` "
                + "ORDER BY r.nuNumRecibo DESC";

        Query query = session.createSQLQuery(sql);
        this.listaRecibos = (ArrayList) query.list();
        session.close();
    }

    /** Convierte Date a String*/
    public String getStringDate(Date d) {
        return FacesUtil.getStringDate(d);
    }

    /** Cuando seleccione un concepto actualice el concepto*/
    public void onChangeConcepto() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Criteria cCatalogo = session.createCriteria(Catalogoservicios.class);
        cCatalogo.add(Restrictions.eq("idCatalogoServicios", this.selectedConcepto));
        Catalogoservicios cs = (Catalogoservicios) cCatalogo.uniqueResult();


        this.detalleRecibo.setCatalogoservicios(cs);


        this.detalleRecibo.setNuPrecio(cs.getNuPrecioDefault());

        this.detalleConcepto = cs.getVcConceptoServicio();

        session.close();
    }

    /** Agregar Pagos*/
    public void addDetallesRecibo() {
        Object[] objPago = new Object[3];
        objPago[0] = this.detalleConcepto;
        objPago[1] = this.detalleRecibo;
        objPago[2] = this.selectedConcepto;
        this.totalPagar += this.detalleRecibo.getNuPrecio() * this.detalleRecibo.getNuCantidad();
        this.arregloDetalles.add(objPago);
        this.vaciarPagos();
    }

    /** Vaciar variables de detalles pagos*/
    public void vaciarPagos() {
        this.detalleRecibo = new Detallerecibo();
        this.detalleConcepto = null;
        this.selectedConcepto = null;
    }

    /** Remover detalles pago*/
    public void removeDetalles() {
        this.detalleRecibo = (Detallerecibo) this.selectedPago[1];
        this.arregloDetalles.remove(this.selectedPago);
        this.totalPagar -= this.detalleRecibo.getNuPrecio() * this.detalleRecibo.getNuCantidad();
        this.selectedPago = new Object[2];
        this.detalleRecibo = new Detallerecibo();
        this.detalleConcepto = null;
    }

    /** Cargar series de los recibos */
    public ArrayList<SelectItem> cargarSeries() {
        ArrayList<SelectItem> lista = new ArrayList<SelectItem>();
        Session session = HibernateUtil.getSessionFactory().openSession();
        Criteria cSerie = session.createCriteria(Serie.class);
        Iterator iter = cSerie.list().iterator();


        while (iter.hasNext()) {
            Serie s = (Serie) iter.next();
            lista.add(new SelectItem(s.getIdSerie(), s.getVcSerie(), ""));
        }

        session.close();

        return lista;
    }

    /** 
     * Getters & Setters
     */
    public Detallerecibo getDetalleRecibo() {
        return detalleRecibo;
    }

    public void setDetalleRecibo(Detallerecibo detalleRecibo) {
        this.detalleRecibo = detalleRecibo;
    }

    public Recibo getRecibo() {
        return recibo;
    }

    public void setRecibo(Recibo recibo) {
        this.recibo = recibo;
    }

    public ArrayList getListaRecibos() {
        return listaRecibos;
    }

    public void setListaRecibos(ArrayList listaRecibos) {
        this.listaRecibos = listaRecibos;
    }

    public Long getSelectedConcepto() {
        return selectedConcepto;
    }

    public void setSelectedConcepto(Long selectedConcepto) {
        this.selectedConcepto = selectedConcepto;
    }

    public String getDetalleConcepto() {
        return detalleConcepto;
    }

    public void setDetalleConcepto(String detalleConcepto) {
        this.detalleConcepto = detalleConcepto;
    }

    public ArrayList<Object[]> getArregloDetalles() {
        return arregloDetalles;
    }

    public void setArregloDetalles(ArrayList<Object[]> arregloDetalles) {
        this.arregloDetalles = arregloDetalles;
    }

    public double getTotalPagar() {
        return totalPagar;
    }

    public void setTotalPagar(double totalPagar) {
        this.totalPagar = totalPagar;
    }

    public Object[] getSelectedPago() {
        return selectedPago;
    }

    public void setSelectedPago(Object[] selectedPago) {
        this.selectedPago = selectedPago;
    }

    public Long getSelectedSerie() {
        return selectedSerie;
    }

    public void setSelectedSerie(Long selectedSerie) {
        this.selectedSerie = selectedSerie;
    }

    public Object[] getSelectedRecibo() {
        return selectedRecibo;
    }

    public void setSelectedRecibo(Object[] selectedRecibo) {
        this.selectedRecibo = selectedRecibo;
    }
}
